import java.net.*;

public class ReliableUDPServer {
    private static final int PACKET_SIZE = 1024;

    public static void main(String[] args) {
        DatagramSocket serverSocket = null;

        try {
            serverSocket = new DatagramSocket(9876);

            while (true) {
                byte[] receiveData = new byte[PACKET_SIZE];
                DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
                serverSocket.receive(receivePacket);

                // Simulate packet loss
                if (Math.random() < 0.3) {
                    System.out.println("Packet loss, sequence number: " + receiveData[0]);
                    continue;
                }

                int sequenceNumber = receiveData[0];
                String message = new String(receivePacket.getData(), 1, receivePacket.getLength() - 1);
                InetAddress clientAddress = receivePacket.getAddress();
                int clientPort = receivePacket.getPort();

                System.out.println("Received from client (seq " + sequenceNumber + "): " + message);

                // Simulate processing
                // For simplicity, just echo the message back to the client
                String response = "Server: " + message;
                byte[] sendData = response.getBytes();

                // Send acknowledgment
                DatagramPacket ackPacket = new DatagramPacket(new byte[]{(byte) sequenceNumber}, 1, clientAddress, clientPort);
                serverSocket.send(ackPacket);

                // Send response
                DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, clientAddress, clientPort);
                serverSocket.send(sendPacket);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (serverSocket != null && !serverSocket.isClosed()) {
                serverSocket.close();
            }
        }
    }
}

